perm filename PUPSFL.C[11,HE] blob
sn#688209 filedate 1982-12-06 generic text, type T, neo UTF8
/* LINTLIBRARY */
/*
* pupsetfilter.c
*
* Builds and sets a packet filter for a pup channel.
*
* Jeffrey Mogul @ Stanford 28-January-1981
*
*/
#define offset(b,a) ( (int)&(b->a) - (int)(b) )
#include <puplib.h>
#include <pupconstants.h>
#include <pupstatus.h>
#include <puppacket.h>
pupsetfilter(Pchan,priority,Fpuptype,Fpupid,Fdstnet,Fdsthost,Fdstsock,
Fsrcnet,Fsrchost,Fsrcsock)
struct PupChan *Pchan; /* open pup channel */
uchar priority; /* filter priority */
uchar *Fpuptype; /* filter on pup type */
ulong *Fpupid; /* filter on pup id */
uchar *Fdstnet; /* filter on destination net */
uchar *Fdsthost; /* filter on destination host */
ulong *Fdstsock; /* filter on destination socket */
uchar *Fsrcnet; /* filter on source net */
uchar *Fsrchost; /* filter on source host */
ulong *Fsrcsock; /* filter on source socket */
{ /* */
register struct enfilter *ef; /* used as a temporary */
register struct PupPacket *pp; /* used as a placeholder */
register struct EnPacket *ep; /* used as a placeholder */
int efterms; /* terms in the filter */
/*
* Here we would switch on Pchan->transport to
* decide what sort of filter mechanism to build;
* currently, the only choice is an enfilter.
*/
ef = &(Pchan->filter.en); /* get address of filter */
efinit(ef,priority); /* init the filter with the given priority */
/* always insure that the ethernet packet type is Pup */
efwdinsert(ef,offset(ep,PacketType),PUP);
efterms = 1; /* always one term, at least */
/* now, conditionally insert each optional test */
/* !!!!! TO AVOID OVERFLOW, BUNCH HOST/NET IF BOTH GIVEN!!!! */
if (Fpuptype) {
efchinsert(ef,ENPACKOVER+offset(pp,PupType),*Fpuptype);
efterms++;
}
if (Fpupid) {
eflginsert(ef,ENPACKOVER+offset(pp,PupID),makelong(*Fpupid));
efterms++;
}
if (Fdstnet) {
efchinsert(ef,ENPACKOVER+offset(pp,PupDst.pk_Net),*Fdstnet);
efterms++;
}
if (Fdsthost) {
efchinsert(ef,ENPACKOVER+offset(pp,PupDst.pk_Host),*Fdsthost);
efterms++;
}
if (Fdstsock) {
eflginsert(ef,ENPACKOVER+offset(pp,PupDst.pk_FSocket),
makelong(*Fdstsock));
efterms++;
}
if (Fsrcnet) {
efchinsert(ef,ENPACKOVER+offset(pp,PupSrc.pk_Net),*Fsrcnet);
efterms++;
}
if (Fsrchost) {
efchinsert(ef,ENPACKOVER+offset(pp,PupSrc.pk_Host),*Fsrchost);
efterms++;
}
if (Fsrcsock) {
eflginsert(ef,ENPACKOVER+offset(pp,PupSrc.pk_FSocket),
makelong(*Fsrcsock));
efterms++;
}
/*
* between each term in the filter, include an AND operation.
* i.e., for n terms, n-1 ANDs.
*/
for (; efterms > 1 ; efterms--) {
if (efAND(ef) != OK) return(FILTERTOOBIG);
}
/* filter is built, insure that it is set onto channel */
ensetfilt(Pchan->ifid, &Pchan->filter.en);
return(OK);
}